别看 DNS 污染闹得欢,现在我用 CoreDNS 将它拉清单

您所在的位置:网站首页 配置windows update得等多久啊 别看 DNS 污染闹得欢,现在我用 CoreDNS 将它拉清单

别看 DNS 污染闹得欢,现在我用 CoreDNS 将它拉清单

2023-04-24 03:22| 来源: 网络整理| 查看: 265

前言

CoreDNS[1] 是 Golang 编写的一个插件式 DNS 服务器,是 Kubernetes 1.13 后所内置的默认 DNS 服务器。CoreDNS 的目标是成为 cloud-native 环境下的 DNS 服务器和服务发现解决方案,即:

Our goal is to make CoreDNS the cloud-native DNS server and service discovery solution.

它有以下几个特性:

插件化(Plugins) 基于 Caddy 服务器框架,CoreDNS 实现了一个插件链的架构,将大量应用端的逻辑抽象成 plugin 的形式(如 Kubernetes 的 DNS 服务发现,Prometheus 监控等)暴露给使用者。CoreDNS 以预配置的方式将不同的 plugin 串成一条链,按序执行 plugin 的逻辑。从编译层面,用户选择所需的 plugin 编译到最终的可执行文件中,使得运行效率更高。CoreDNS 采用 Go 编写,所以从具体代码层面来看,每个 plugin 其实都是实现了其定义的 interface 的组件而已。第三方只要按照 CoreDNS Plugin API 去编写自定义插件,就可以很方便地集成于 CoreDNS。配置简单化 引入表达力更强的 DSL[2],即 Corefile 形式的配置文件(也是基于 Caddy 框架开发)。一体化的解决方案 区别于 kube-dns,CoreDNS 编译出来就是一个单独的二进制可执行文件,内置了 cache,backend storage,health check 等功能,无需第三方组件来辅助实现其他功能,从而使得部署更方便,内存管理更为安全。

其实从功能角度来看,CoreDNS 更像是一个通用 DNS 方案(类似于 BIND),然后通过插件模式来极大地扩展自身功能,从而可以适用于不同的场景(比如 Kubernetes)。正如官方博客所说:

CoreDNS is powered by plugins.

1. Corefile 介绍

Corefile 是 CoreDNS 的配置文件(源于 Caddy 框架的配置文件 Caddyfile),它定义了:

server 以什么协议监听在哪个端口(可以同时定义多个 server 监听不同端口)server 负责哪个 zone 的权威(authoritative)DNS 解析server 将加载哪些插件

常见地,一个典型的 Corefile 格式如下所示:

ZONE:[PORT] {  [PLUGIN] ... }ZONE : 定义 server 负责的 zone,PORT 是可选项,默认为 53;PLUGIN : 定义 server 所要加载的 plugin。每个 plugin 可以有多个参数;

比如:

. {     chaos CoreDNS-001 }

上述配置文件表达的是:server 负责根域 . 的解析,其中 plugin 是 chaos 且没有参数。

定义 server

一个最简单的配置文件可以为:

.{}

即 server 监听 53 端口并不使用插件。**如果此时在定义其他 server,要保证监听端口不冲突;如果是在原来 server 增加 zone,则要保证 zone 之间不冲突,**如:

.    {} .:54 {}

另一个 server 运行于 54 端口并负责根域 . 的解析。

又如:

example.org {     whoami } org {     whoami }

同一个 server 但是负责不同 zone 的解析,有不同插件链。

定义 Reverse Zone

跟其他 DNS 服务器类似,Corefile 也可以定义 Reverse Zone(反向解析 IP 地址对应的域名):

0.0.10.in-addr.arpa {     whoami }

或者简化版本:

10.0.0.0/24 {     whoami }

可以通过 dig 进行反向查询:

$ dig -x 10.0.0.1使用不同的通信协议

CoreDNS 除了支持 DNS 协议,也支持 TLS 和 gRPC,即 DNS-over-TLS[3] 和 DNS-over-gRPC 模式:

tls://example.org:1443 { #... }2. 插件的工作模式

当 CoreDNS 启动后,它将根据配置文件启动不同 server ,每台 server 都拥有自己的插件链。当有 DNS 请求时,它将依次经历如下 3 步逻辑:

如果有当前请求的 server 有多个 zone,将采用贪心原则选择最匹配的 zone;一旦找到匹配的 server,按照 plugin.cfg[4] 定义的顺序执行插件链上的插件;每个插件将判断当前请求是否应该处理,将有以下几种可能:请求被当前插件处理 插件将生成对应的响应并回给客户端,此时请求结束,下一个插件将不会被调用,如 whoami 插件;请求被当前插件以 Fallthrough 形式处理 如果请求在该插件处理过程中有可能将跳转至下一个插件,该过程称为 fallthrough,并以关键字 fallthrough 来决定是否允许此项操作,例如 host 插件,当查询域名未位于 /etc/hosts,则调用下一个插件;请求在处理过程被携带 Hint 请求被插件处理,并在其响应中添加了某些信息(hint)后继续交由下一个插件处理。这些额外的信息将组成对客户端的最终响应,如 metric 插件;3. CoreDNS 如何处理 DNS 请求

如果 Corefile 为:

coredns.io:5300 {     file db.coredns.io } example.io:53 {     log     errors     file db.example.io } example.net:53 {     file db.example.net } .:53 {     kubernetes     proxy . 8.8.8.8     log     health     errors     cache }

从配置文件来看,我们定义了两个 server(尽管有 4 个区块),分别监听在 5300 和 53 端口。其逻辑图可如下所示:

每个进入到某个 server 的请求将按照 plugin.cfg 定义顺序执行其已经加载的插件。

从上图,我们需要注意以下几点:

尽管在 .:53 配置了 health 插件,但是它并为在上面的逻辑图中出现,原因是:该插件并未参与请求相关的逻辑(即并没有在插件链上),只是修改了 server 配置。更一般地,我们可以将插件分为两种: Normal 插件:参与请求相关的逻辑,且插入到插件链中;其他插件:不参与请求相关的逻辑,也不出现在插件链中,只是用于修改 server 的配置,如 health,tls 等插件;4. 配置 CoreDNS

既然 CoreDNS 如此优秀,我用它来抵御伟大的防火长城岂不美哉?研究了一圈,发现技术上还是可行的,唯一的一个缺点是不支持使用代理,不过你可以通过 proxychians-ng[5] 或 proxifier[6] 来强制使用代理。下面开始折腾。

具体的思路其实非常简单,就是将国内的域名查询请求转发到 114 等国内的公共 DNS 服务器,将国外的域名查询请求转发到 8.8.8.8 等国外的公共 DNS 服务器。然而 CoreDNS 的插件链有点反直觉,同一个插件链上的每一个插件只能出现一次,如果只使用 forward 插件是满足不了需求的。

CoreDNS 原来还有个插件叫 proxy,功能和 forward 类似,目测好像同时利用 proxy 和 forward 插件就可以实现咱的需求了。但理想与现实的差距总是很大,不知道从什么时候开始,CoreDNS 官方编译的二进制文件已经没有 proxy 插件了,真是气人。

dnsredir

偶然间发现了一个第三方插件 dnsredir[7],目测可以解决我的所有问题。该插件综合了 proxy 和 forward 插件的所有优点,支持 UDP、TCP、DNS-over-TLS 和 DNS-over-HTTPS,也支持多个后端,还具备健康检查和故障转移的功能,真是太香了!

它的语法是这样的:

dnsredir FROM... {     to TO... }FROM... 是一个文件列表,包含了匹配的域名和解析该域名的服务器,说白了就是 dnsmasq 所使用的格式,直接看例子:server=/0-100.com/114.114.114.114 server=/0-100.com/114.114.114.114

为什么要用这种格式呢?当然是为了方便啦。

为什么这样会方便呢?当然是为了可以直接用上 FelixOnMars的大陆区域名列表[8]了。。。FelixOnMars 同时还提供了 Google 和 Apple 的域名列表,这在某些地区某些ISP可以得到国内镜像的 IP,从而加速访问,想想就刺激。

当然,除了使用文件列表外,还可以使用 .,类似于上面所说的根域。这个插件最大的亮点是可以在插件链中重复使用 dnsredir 插件,只要 FROM... 不重复就行。to TO... 用来将 DNS 解析请求发给上游 DNS 服务器。支持几乎所有 DNS 协议,例如:dns://1.1.1.1 8.8.8.8 tcp://9.9.9.9 udp://2606:4700:4700::1111    tls://[email protected] tls://8.8.8.8 tls://dns.quad9.net    doh://cloudflare-dns.com/dns-query json-doh://1.1.1.1/dns-query json-doh://dns.google/resolve ietf-doh://dns.quad9.net/dns-query增强版 CoreDNS

dnsredir 虽香,但大家别忘了,它是第三方插件,官方默认的二进制文件是不包含该插件的。你可以选择自己编译,但如果经常需要升级怎么办?总不能每次都手动编译吧,也太累了。

好在有位大佬已经通过 CI/CD 流程将所需的第三方插件都集成编译进去了,并定期更新,简直就是我等的福音。大佬的项目地址为:

https://github.com/missdeer/coredns_custom_build[9]

现在只需要下载对应操作系统的二进制文件,到处拷贝,就可以运行了。

下面统统以 MacOS 为例作讲解。Openwrt 的玩法也一样,参考本文的方法论即可,具体本文就不展开了。

直接下载二进制文件:

$ wget 'https://appveyorcidatav2.blob.core.windows.net/missdeer-15199/coredns-custom-build/1-7-1-514/idbodwxwywg1xgdg/distrib/coredns-linux-amd64.zip?sv=2015-12-11&sr=c&sig=BhMWcOVtDuaETyz2DcjpOr9GdvkpNVOqoIa7iWFpFNQ%3D&st=2020-12-23T15%3A26%3A19Z&se=2020-12-23T15%3A32%3A19Z&sp=r' $ $ tar zxf coredns-linux-amd64.zip $ mv coredns-linux-amd64/coredns /usr/local/bin/配置

要深入了解 CoreDNS,请查看其文档[10],及 plugins 的介绍[11]。下面是我的配置文件:

cat > /usr/local/etc/Corefile 


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3